package net.xdclass.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import net.xdclass.enums.BizCodeEnum;
import net.xdclass.enums.SendCodeEnum;
import net.xdclass.feign.CouponFeignService;
import net.xdclass.interceptor.LoginInterceptor;
import net.xdclass.mapper.UserMapper;
import net.xdclass.model.LoginUser;
import net.xdclass.model.UserDO;
import net.xdclass.request.NewUserCouponRequest;
import net.xdclass.request.UserLoginRequest;
import net.xdclass.request.UserRegisterRequest;
import net.xdclass.service.NotifyService;
import net.xdclass.service.UserService;
import net.xdclass.util.CommonUtil;
import net.xdclass.util.JWTUtil;
import net.xdclass.util.JsonData;
import net.xdclass.vo.UserVO;
import org.apache.commons.codec.digest.Md5Crypt;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

/**
 * @Description:
 * @Author:xuezhen
 * @CreateDate:2021/4/12 22:49
 * @UpdateUser:
 * @UpdateDate:
 * @UpdateRemark:
 * @Version:v2.0
 */
@Slf4j
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private CouponFeignService couponFeignService;

    @Autowired
    private NotifyService notifyService;

    @Autowired
    private UserMapper userMapper;

//    @Transactional(rollbackFor=Exception.class,propagation = Propagation.REQUIRED)
//    @GlobalTransactional
    @Override
    public JsonData register(UserRegisterRequest userRegisterRequest) {
        // 邮箱验证码的验证
        Boolean checkCode = false;
        if(StringUtils.isNotBlank(userRegisterRequest.getMail())){
            checkCode = notifyService.checkCode(SendCodeEnum.USER_REGISTER, userRegisterRequest.getMail(), userRegisterRequest.getCode());
        }
        if(!checkCode){
            JsonData.buildSuccess(BizCodeEnum.CODE_ERROR);
        }
        UserDO userDO = new UserDO();
        BeanUtils.copyProperties(userRegisterRequest,userDO);
        userDO.setCreateTime(new Date());
        userDO.setSecret("$1$"+ CommonUtil.getStringNumRandom(8));
        String cryptPwd = Md5Crypt.md5Crypt(userRegisterRequest.getPwd().getBytes(), userDO.getSecret());
        // 设置密码
        userDO.setPwd(cryptPwd);
        // 密码加密
        // 账号唯一性检查
        if(checkUnique(userDO.getMail())){
            // 插入数据库
            int rows = userMapper.insert(userDO);
            log.info("rows:{},注册成功:{}",rows,userDO.toString());
            // 初始化信息,新注册用户福利发放
            userRegisterInitTask(userDO);
            return JsonData.buildSuccess();
        }else{
            JsonData.buildSuccess(BizCodeEnum.ACCOUNT_REPEAT);
        }
        return null;
    }

    @Override
    public JsonData login(UserLoginRequest userLoginRequest) {
        // 根据mail寻找记录
        List<UserDO> userDOList = userMapper.selectList(new QueryWrapper<UserDO>().eq("mail", userLoginRequest.getMail()));
        if(userDOList != null && userDOList.size() == 1){
            // 存在根据秘钥和用户密码进行加密和数据库密文进行匹配
            UserDO userDO = userDOList.get(0);
            String cryptPwd = Md5Crypt.md5Crypt(userLoginRequest.getPwd().getBytes(), userDO.getSecret());
            if(cryptPwd.equals(userDO.getPwd())){
                // 登录成功生成token->redis+过期时间
                // jwt可以解密不需要依赖于redis
                LoginUser build = LoginUser.builder().build();
                BeanUtils.copyProperties(userDO,build);
                String token = JWTUtil.generatorJsonWebToken(build);
                return JsonData.buildSuccess(token);
            }else{
                return JsonData.buildResult(BizCodeEnum.ACCOUNT_PWD_ERROR);
            }
        }else{
            return JsonData.buildResult(BizCodeEnum.ACCOUNT_UNREGISTER);
        }
    }

    @Override
    public UserVO findUserDetil() {
        LoginUser loginUser = LoginInterceptor.threadLocal.get();
        UserDO userDO = userMapper.selectOne(new QueryWrapper<UserDO>().eq("id", loginUser.getId()));
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(userDO,userVO);
        return userVO;
    }

    /**
     * 校验用户账号唯一
     * @param mail 邮箱
     * @return 是否唯一
     */
    private boolean checkUnique(String mail) {
        QueryWrapper<UserDO> query = new QueryWrapper<UserDO>().eq("mail",mail);
        List<UserDO> userDOS = userMapper.selectList(query);
        return userDOS.size() == 0;
    }

    /**
     * 用户注册,初始化福利信息TODO
     * @param userDO
     */
    private void userRegisterInitTask(UserDO userDO){
        NewUserCouponRequest request = new NewUserCouponRequest();
        request.setUserId(userDO.getId());
        request.setName(userDO.getName());
        JsonData jsonData = couponFeignService.addNewUserCoupon(request);
        log.info("发放新用户注册优惠券:{},结果:{}",request,jsonData.toString());
    }
}
